package com.foreverwin.jzymes.production.inspect.service.impl;

import com.foreverwin.jzymes.common.domain.CarrierBind;
import com.foreverwin.jzymes.common.domain.NcData;
import com.foreverwin.jzymes.common.mapper.CarrierBindMapper;
import com.foreverwin.jzymes.common.mapper.NcDataMapper;
import com.foreverwin.jzymes.common.service.*;
import com.foreverwin.jzymes.framework.exception.BusinessException;
import com.foreverwin.jzymes.framework.util.I18nUtil;
import com.foreverwin.jzymes.framework.util.ObjectMapperUtil;
import com.foreverwin.jzymes.production.inspect.service.IInspectAlarmDisposeAdviceService;
import com.foreverwin.jzymes.production.nc.service.ICarrierNCDisposeAdviceService;
import com.foreverwin.jzymes.production.sfc.mapper.SFCMapper;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

@Service
public class InspectAlarmDisposeAdviceServiceImpl implements IInspectAlarmDisposeAdviceService {
    @Autowired
    ISiteAdviceService siteAdviceService;
    @Autowired
    IResourceAdviceService resourceAdviceService;
    @Autowired
    ICommonService commonService;
    @Autowired
    ICarrierBindAdviceService carrierBindAdviceService;
    @Autowired
    INCDataAdviceService ncDataAdviceService;
    @Autowired
    INCCodeAdviceService ncCodeAdviceService;
    @Autowired
    ISfcBatchPassLogAdviceService sfcBatchPassLogAdviceService;
    @Autowired
    IActivityLogAdviceService activityLogAdviceService;
    @Autowired
    ICarrierNCDisposeAdviceService carrierNCDisposeAdviceService;
    @Autowired
    CarrierBindMapper carrierBindMapper;
    @Autowired
    NcDataMapper ncDataMapper;
    @Autowired
    SFCMapper sfcMapper;


    @Transactional( propagation = Propagation.REQUIRED, rollbackFor = Exception.class )
    public void disposeAlarmNC( Map<String,Object> jsonMap ){
        /**检查不良处置字段*/
        checkFieldsForDisposeNC( jsonMap );

        /**检查不良明细*/
        List<Map<String,Object>> ncList = (List<Map<String, Object>>) jsonMap.get( "ncList" );
        Assert.isTrue( ncList != null && ncList.size() > 0, I18nUtil.getI18nText( "production.nc.ncListNotNull" ) );

        /**添加公用字段*/
        jsonMap.remove( "ncList" );
        for( Map<String,Object> map : ncList ){
            map.put( "site", jsonMap.get( "site" ) );
            map.put( "carrier", jsonMap.get( "carrier" ) );
        }
        List<NcData> ncDataList = ObjectMapperUtil.convertList( ncList, NcData.class );
        disposeAlarmNC( (String) jsonMap.get( "site" ), (String) jsonMap.get("carrier"), (String) jsonMap.get("resrce"), (String) jsonMap.get("operation"), ncDataList );
    }


    public void disposeAlarmNC( String site, String carrier, String resource, String operation, List<NcData> ncDataList ){
        /**检查本体是否绑定*/
        List<CarrierBind>  carrierBindList = carrierBindAdviceService.existCarrierBindonBind( site, carrier );

        /**检查本体在全检工序是否已过站*/
        boolean passed = commonService.checkCarrierPassOnOperation( carrierBindList.get(0), operation );
        Assert.isTrue( passed == false, I18nUtil.getI18nText( "production.nc.carrierPassOnOperation", new Object[]{ carrier, operation } ) );

        /**检查不良项目列表*/
        ncDataList = checkNcDataList( ncDataList );

        Date updatedDateTime = new Date();


        /**处置一夹、二夹未处置的nc*/
        //disposeCncNC( site, carrier, operation, ncDataList, updatedDateTime );
        /**处置全检拦截报废nc*/
        //disposeInspectNC( site, carrier, resource, operation, ncDataList, updatedDateTime );

        for( NcData ncData : ncDataList ){
            ncData.setOperation( operation );
            ncData.setResrce( resource );
            ncData.setUpdatedDateTime( updatedDateTime );
            ncDataMapper.deleteNcDataById( ncData.getHandle() );
            commonService.saveNcData( ncData, true );
        }

        carrierBindList = carrierBindAdviceService.findCarrierBindOnBind( site, carrier );
        if( carrierBindList != null && carrierBindList.size() > 0 ){
            if( !carrierBindList.get(0).getNextOperation().equals( operation ) ){
                String prevOperation = commonService.findSfcPrevOperation( site, carrierBindList.get(0).getItemBo(), operation );
                commonService.sfcPassByCarrierOnOperation( site, carrier, prevOperation, updatedDateTime );
            }
        }

    }


    /**
     * 处置一夹、二夹未处置的nc
     *
     * @param site
     * @param carrier
     * @param operation
     * @param ncDataList
     */
    public void disposeCncNC( String site, String carrier, String operation, List<NcData> ncDataList, Date updatedDateTime ){
        boolean flag = false;
        while( true ){
            /**检查本体是否绑定*/
            List<CarrierBind>  carrierBindList = carrierBindAdviceService.existCarrierBindonBind( site, carrier );

            String nextOperation = carrierBindList.get(0).getNextOperation();
            if( nextOperation.equals( operation ) ){
                break;
            }
            List<NcData> nList = findNcDataOnOperation( ncDataList, nextOperation );
            if( nList.size() == 0 && flag == false ){
                for( CarrierBind carrierBind : carrierBindList ){
                    carrierBind.setNextOperation( commonService.findSfcNextOperation( carrierBind.getSite(), carrierBind.getItemBo(), carrierBind.getNextOperation() ) );
                    carrierBindMapper.updateCarrierBind( carrierBind );
                }
            }
            if( nList.size() == 0 && flag == true ){
                commonService.sfcPassByCarrierOnOperation( site, carrier, nextOperation, updatedDateTime );
            }
            if( nList.size() > 0 ){
                flag = true;
                carrierNCDisposeAdviceService.disposeCarrierNC( site, carrier, nList.get(0).getResrce(), nList, updatedDateTime, true );

            }
        }
    }


    /**
     * 处置全检拦截报废nc
     * 处置方式合格，本体保留在全检工序不过站
     * 处置方式报废，本体物料解绑报废
     *
     * @param site
     * @param carrier
     * @param operation
     * @param ncDataList
     * @param updatedDateTime
     */
    public void disposeInspectNC( String site, String carrier, String resource, String operation, List<NcData> ncDataList, Date updatedDateTime ){
        List<NcData> nList = findNcDataOnOperation( ncDataList, operation );
        if( nList.size() > 0 ){
            for( NcData ncData : nList ){
                ncData.setUpdatedDateTime( updatedDateTime );
                ncDataMapper.deleteNcDataById( ncData.getHandle() );
                commonService.saveNcData( ncData, true );
            }
        }
    }



    public List<NcData> findNcDataOnOperation( List<NcData> ncList, String operation ){
        List<NcData> ncDataList = new ArrayList<>();
        for( NcData ncData : ncList ){
            if( ncData.getOperation().equals( operation ) ){
                ncDataList.add( ncData );
            }
        }
        return ncDataList;
    }

    /**
     * 检查不良项目列表
     *
     * @param ncList
     * @return
     */
    public List<NcData> checkNcDataList( List<NcData> ncList ){
        List<NcData> ncDataList = new ArrayList<>();
        for( NcData ncData : ncList ){
            if( StringUtils.isBlank( ncData.getDisposition() ) ){
                throw BusinessException.build("production.nc.carrierNcNotDispose", new String[]{ ncData.getCarrier(), ncData.getItemBo(),ncData.getNcCode() } );
            }
            if( StringUtils.isBlank( ncData.getOperation() ) ){
                throw BusinessException.build( "production.nc.ncOperationNotBlank", new String[]{ ncData.getCarrier(), ncData.getItemBo(),ncData.getNcCode() } );
            }
            /**检查本体物料不良项目是否存在*/
            NcData ncData1 = ncDataAdviceService.findItemOpenNcDataFromDate( ncData.getSite(), ncData.getCarrier(), ncData.getItemBo(), ncData.getOperation() );
            Assert.notNull( ncData1, I18nUtil.getI18nText("production.nc.carrierItemNCNotExist", new Object[]{ ncData.getCarrier(), ncData.getItemBo(), ncData.getOperation() } ) );
            ncData1.setDisposition( ncData.getDisposition() );

            String futureOperation = ncCodeAdviceService.findNCValidOper( ncData1.getSite(), ncData1.getNcCode() );
            if( StringUtils.isNotBlank( futureOperation ) ){
                ncData1.setOperation( futureOperation );
            }
            ncDataList.add( ncData1 );
        }
        return ncDataList;
    }

    /**
     * 检查不良处置字段
     *
     * @param jsonMap
     */
    public void checkFieldsForDisposeNC( Map<String,Object> jsonMap ){
        /**检查站点*/
        siteAdviceService.existSite((String) jsonMap.get( "site" ));
        /**检查设备*/
        Map<String,Object> resourceMap = resourceAdviceService.existResource( (String) jsonMap.get( "site" ), (String) jsonMap.get( "resrce" ));
        /**检查工序*/
        String operation = resourceAdviceService.findOperationByResource( resourceMap );
        jsonMap.put( "operation", operation );
        /**检查本体*/
        Assert.hasText( ( String )jsonMap.get( "carrier" ), I18nUtil.getI18nText( "common.carrierNotBlank" ));
    }
}
